import urllib
from urllib.parse import urlencode
import json
import http.client

from django.shortcuts import render
from rest_framework.views import APIView
from QQLoginTool.QQtool import OAuthQQ
from django.conf import settings
from rest_framework.response import Response
from rest_framework import status
import logging
from rest_framework_jwt.settings import api_settings


from .models import OAuthQQUser, SinaAuthUser
from .utils import generate_save_user_token
from .serializers import QQAuthUserSerializer, SinaAuthUserSerializer
from carts.utils import merge_cart_cookie_to_redis



logger = logging.getLogger('django')

# Create your views here.


class WeiboAuthURLView(APIView):
    """生成微博登录扫码链接"""

    def get(self, request):
        # 1.获取next(从那里去到login界面)参数路径
        next = request.query_params.get('next')
        if not next:  # 如果没有指定来源将来登录成功就回到首页
            next = '/'
        data_dict = {
            # 'response_type': 'code',
            'client_id': "3305669385",
            'redirect_uri': "http://www.meiduo.site:8080/sina_callback.html",
            'state': next
        }
        login_url = "https://api.weibo.com/oauth2/authorize?" + urlencode(data_dict)
        print(login_url)
        return Response({"login_url": login_url})


class WeiboAuthUserView(APIView):
    """OAuth2.0认证:处理扫码回调操作"""

    def get(self, request1):
        # 提取code请求参数
        code = request1.query_params.get('code')
        if not code:
            return Response({'message': '缺少code'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            #请求数据
            textmod = {"grant_type": "authorization_code",
                       "client_id": "3305669385",
                       "client_secret": "74c7bea69d5fc64f5c3b80c802325276",
                       "code": code,
                       "redirect_uri": "http://www.meiduo.site:8080/sina_callback.html"}
            textmod = urllib.parse.urlencode(textmod)

            #请求头
            header_dict = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
            url = 'https://api.weibo.com/oauth2/access_token'
            #创建连接对象
            conn = http.client.HTTPSConnection("api.weibo.com")
            #发送POST请求
            conn.request(method="POST", url=url, headers=header_dict, body=textmod)
            response = conn.getresponse()
            res = response.read()
            # print(res)
            resp = json.loads(res)
            print(resp)
            access_token = resp['access_token']
        except:
            return Response({'message': '新浪登录异常'},status=status.HTTP_400_BAD_REQUEST)

        # 使用access_token查询该Sina用户是否在美多商城中绑定过用户
        try:
            oauthsinauser_model = SinaAuthUser.objects.get(access_token=access_token)
        except SinaAuthUser.DoesNotExist:
            # 如果access_token没绑定美多商城用户，创建用户并绑定到access_token
            access_token= generate_save_user_token(access_token)
            return Response({'access_token': access_token})
        else:
            # 如果openid已绑定美多商城用户，直接生成JWT token，并返回
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER  # 加载生成载荷函数
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER  # 加载生成token函数
            user = oauthsinauser_model.user
            payload = jwt_payload_handler(user)  # 生成载荷
            token = jwt_encode_handler(payload)  # 根据载荷生成token

            response = Response({
                'token': token,
                'user_id': user.id,
                'username': user.username
            })

            merge_cart_cookie_to_redis(request1, user, response)

            return response

    def post(self, request):
        """使用access_token绑定美多用户"""
        # 获取序列化器对象
        serializer = SinaAuthUserSerializer(data=request.data)
        # 开启校验  # 调用序列化器中的validate
        serializer.is_valid(raise_exception=True)

        # 保存校验结果，并接收  #调用序列化器中的create
        user = serializer.save()

        # 生成JWT token，并响应
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        response = Response({
            'token': token,
            'user_id': user.id,
            'username': user.username
        })

        merge_cart_cookie_to_redis(request, user, response)

        return response






class QQAuthUserView(APIView):
    """扫码成功后回调处理"""

    def get(self, request):
        # 查询参数中的code 参数
        code = request.query_params.get('code')
        if not code:
            return Response({'message':'缺少code'}, status=status.HTTP_400_BAD_REQUEST)
        # 创建qq登录工具对象
        oauthqq = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                          client_secret=settings.QQ_CLIENT_SECRET,
                          redirect_uri=settings.QQ_REDIRECT_URI)
                        #  state 有默认值 此处不传
        try:
            # 2. 通过cookie向QQ服务器请求获取access_token
            access_token = oauthqq.get_access_token(code)
            # 3.通过access_token 向服务器请求获取openid
            openid = oauthqq.get_open_id(access_token)
        except Exception as error:
            logger.info(error)
            return Response({'message':'QQ服务器异常'}, status=status.HTTP_503_SERVICE_UNAVAILABLE)

        try:
            # 4.查询openid是否绑定过用户
            qqauth_model = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 如果openid 没有绑定过商城的用户
            # 把openid进行加密安全处理， 再响应给浏览器
            openid_sin = generate_save_user_token(openid)
            return Response({'access_token':openid_sin})

        else:
            # 如果openid 已经绑定过商城的用户 生成jwt_token 直接登录
            # 手动生成 token
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER  # 加载生成载荷函数
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER  # 加载生成token
            # 获取user对象
            user = qqauth_model.user
            payload = jwt_payload_handler(user)  # 生成载荷
            token = jwt_encode_handler(payload)  # 根据载荷生成token

            # 做 cookie购物车合并到redis操作
            response = Response({
                'token': token,
                'username': user.username,
                'user_id': user.id
            })
            # 做cookie购物车合并到redis操作
            merge_cart_cookie_to_redis(request, user, response)

            return response


    def post(self, request):

        # 创建序列化器对象， 进行反序列化
        serializer = QQAuthUserSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()

        # 手动生成jwt_token
        # 手动生成 token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER  # 加载生成载荷函数
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER  # 加载生成token
        # 获取user对象

        payload = jwt_payload_handler(user)  # 生成载荷
        token = jwt_encode_handler(payload)  # 根据载荷生成token
        return Response({
            'token': token,
            'username': user.username,
            'user_id': user.id
        })


class QQAuthURLView(APIView):
    """生成QQ扫码url"""

    def get(self, request):
        # 1 获取next (从哪里到login界面)的参数路径
        next = request.query_params.get('next')
        if not next:
            # 若没有指定来源，登录成功后就回首页
            next = '/'

    # QQ登录参数
        """
        QQ_CLIENT_ID = '101514053'
        QQ_CLIENT_SECRET = '1075e75648566262ea35afa688073012'
        QQ_REDIRECT_URI = 'http://www.meiduo.site:8080/oauth_callback.html'
        oauthqq = OAuthQQ(client_id='101514053', 
                  client_secret='1075e75648566262ea35afa688073012', 
                  redirect_uri='http://www.meiduo.site:8080/oauth_callback.html',
                  state=next)
        """
        # 2 创建QQ登录sdk 对象
        oauthqq = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                          client_secret=settings.QQ_CLIENT_SECRET,
                          redirect_uri= settings.QQ_REDIRECT_URI,
                          state=next)
        # 调用包含的get_qq_url 方法获取拼接号的扫码连接
        login_url = oauthqq.get_qq_url()

        # 4. 把扫码url响应给前端
        return Response({'login_url': login_url})